#-------------------------------------------------------------------------------
# Name:        Python Game Challenge
# Purpose:      The Python Game Challenge
#
# Author:      Kappy
#
# Created:     18/06/2013
# Copyright:   (c) Kappy 2013
# Licence:     <your licence>
#-------------------------------------------------------------------------------
import random

#Asks the player if they want to stack the current card
def drawAsk() :
    print('Do you want to draw a card?')
    return raw_input().lower().startswith('y')

def stackAsk() :
    print('Do you want to stack this card?')
    return raw_input().lower().startswith('y')

def drawStackAsk() :
    print('Do you want to take a card from the playing field?')
    return raw_input().lower().startswith('y')

def foundationAsk() :
    print('Do you want to stack this card to the foundation?')
    return raw_input().lower().startswith('y')

#Asks the player if they'd like to play again
def playAgain() :
    print('Do you want to play again? (Yes or No)')
    return raw_input().lower().startswith('y')
    print(" ")

def showTopCard(cardStack) :
    topCard = cardStack.pop()
    cardStack.add(topCard)
    return topCard

#Class to create a card
class Card :
    def __init__(self, rank, suit) :
        self.rank = rank
        self.suit = suit

    def Rank(self) :
        return "Ace Two Three Four Five Six Seven Eight Nine Ten Jack Queen King".split()[self.rank]

    def Suit(self) :
        return "Hearts Spades Clubs Diamonds".split()[self.suit]

    def __str__(self) :
        return self.Rank() + " of " + self.Suit()

#Class to create a hand
class Hand :
    def __init__(self) :
        self.cards = []

    def add(self, card) :
        self.cards.append(card)

    def Rank(self) :
        cardRank = 0
        for card in self.cards :
            cardRank = card.rank
        return cardRank

    def Suit(self) :
        cardSuit = 0
        for card in self.cards :
            cardSuit = card.suit
        return cardSuit

    def Color(self) :
        cardColor = "Green"
        for card in self.cards :
            if card.suit == 0 or card.suit == 3 :
                cardColor = "Red"
            elif card.suit == 1 or card.suit == 2 :
                cardColor = "Black"
        return cardColor

    def Show(self, show_only = None) :
        if not show_only :
            for k in self.cards :
                print (k)
        else :
            if isinstance(show_only, int) :
                print (self.cards[show_only])
            elif isinstance(show_only, (list,tuple)) :
                for idx in show_only :
                    print (self.cards[idx])

    def pop(self) :
        return self.cards.pop()

    def length(self) :
        return len(self);

#Class for card stacks (discard pile and the stack you're using
class cardStack :
    def __init__(self) :
        self.cards = []

    def add(self, card) :
        self.cards.append(card)

    def Rank(self) :
        cardRank = 0
        for card in self.cards :
            cardRank = card.rank
        return cardRank

    def Suit(self) :
        cardSuit = 0
        for card in self.cards :
            cardSuit = card.suit
        return cardSuit

    def Color(self) :
        cardColor = "Green"
        for card in self.cards :
            if card.suit == 0 or card.suit == 3 :
                cardColor = "Red"
            elif card.suit == 1 or card.suit == 2 :
                cardColor = "Black"
        return cardColor

    def Show(self, show_only = None) :
        if not show_only :
            for k in self.cards :
                print (k)
        else :
            if isinstance(show_only, int) :
                print (self.cards[show_only])
            elif isinstance(show_only, (list,tuple)) :
                for idx in show_only :
                    print (self.cards[idx])

    def empty(self) :
        return self.head == None

    def pop(self) :
        return self.cards.pop()

    def length(self) :
        return len(self);

#Creates the deck the player will use
class deck :
    def __init__(self ):
        self.cards = []
        for i in range(4) :
            for j in range(13) :
                self.cards.append(Card(j, i))
        random.shuffle(self.cards)

    def shuffle(self ) :
        random.shuffle(self.cards)

    def pop(self) :
        return self.cards.pop()

    def empty(self) :
        return self.head == None

#Initialize deck
d = deck()

#Initialize 7 stacks for cards

stack1 = cardStack() #1 card
stack2 = cardStack() #2 cards
stack3 = cardStack() #3 cards
stack4 = cardStack() #4 cards
stack5 = cardStack() #5 cards
stack6 = cardStack() #6 cards
stack7 = cardStack() #7 cards

#Initialize foundation stacks
heartStack = cardStack()
spadeStack = cardStack()
clubStack = cardStack()
diamondStack = cardStack()

#Initialize discard pile and draw deck
discardPile = cardStack()
drawDeck = cardStack()

#Intialize player hand
playerHand = Hand() #This is for the drawDeck Hand
tempHand = Hand() #This is for taking cards from stacks and placing it
                  #somewhere else

#Intialize some variables to play
stackNum = -1  #stackNum is the variable you will give to stack onto one
               #of the 7 stacks on the playing field
foundationNum = -1 #foundationNum is the variable to choose which foundation
                   #stack you will stack to

finished = False

print("Welcome to Solitaire!")
print("Setting up the game board...")
print(" ")

#Set up the game board

stack1.add(d.pop())
stack1Card = showTopCard(stack1)
print("Stack 1: " + str(stack1Card))

stack2.add(d.pop())
stack2.add(d.pop())
stack2Card = showTopCard(stack2)
print("Stack 2: " + str(stack2Card))

stack3.add(d.pop())
stack3.add(d.pop())
stack3.add(d.pop())
stack3Card = showTopCard(stack3)
print("Stack 3: " + str(stack3Card))

stack4.add(d.pop())
stack4.add(d.pop())
stack4.add(d.pop())
stack4.add(d.pop())
stack4Card = showTopCard(stack4)
print("Stack 4: " + str(stack4Card))

stack5.add(d.pop())
stack5.add(d.pop())
stack5.add(d.pop())
stack5.add(d.pop())
stack5.add(d.pop())
stack5Card = showTopCard(stack5)
print("Stack 5: " + str(stack5Card))

stack6.add(d.pop())
stack6.add(d.pop())
stack6.add(d.pop())
stack6.add(d.pop())
stack6.add(d.pop())
stack6.add(d.pop())
stack6Card = showTopCard(stack6)
print("Stack 6: " + str(stack6Card))

stack7.add(d.pop())
stack7.add(d.pop())
stack7.add(d.pop())
stack7.add(d.pop())
stack7.add(d.pop())
stack7.add(d.pop())
stack7.add(d.pop())
stack7Card = showTopCard(stack7)
print("Stack 7: " + str(stack7Card))

i = 0
while(i < 24) :
    drawDeck.add(d.pop())
    i += 1

print(" ")

print("Heart foundation stack is empty")
print("Spade foundation stack is empty")
print("Club foundation stack is empty")
print("Diamond foundation stack is empty")

print(" ")

while True :
    if(drawAsk()) :
        if(drawDeck.length() >= 3) :
            if(playerHand.length() != 0) :
                i = 0
                while(i < len(playerHand)) :
                    discardPile.add(playerHand.pop())
            else :
                i = 0
                while(i < 3) :
                    playerHand.add(drawDeck.pop())
        else :
            if(len(playerHand) != 0) :
                i = 0
                while(i < len(playerHand)) :
                    discardPile.add(playerHand.pop())
            else :
                i = 0
                while(i < len(drawDeck)) :
                    playerHand.add(drawDeck.pop())

        print("Your 3 cards are: ")
        playerHand.Show()

        print(" ")

        playerHandCard = showTopCard(playerHand)
        print("Do you want to stack " + str(playerHandCard) + "?")
        stackDrawCard = raw_input().lower().startswith('y')

        if(stackDrawCard) :
            if(foundationAsk()) :
                print('Please enter which foundation you want to stack to')
                foundationNum = input()
                foundationNum = int(foundationNum)
                if(foundationNum == 0) :
                    if(playerHandCard.Suit() == heartStack.Suit()) :
                        if(playerHandCard.Rank() > heartStack.Rank()) :
                            heartStack.add(playerHand.pop())
                        #else :
                            #print("Invalid move. " + str(playerHandCard) is)
            else :
                print("Please enter which stack you want to stack " +
                str(playerHandCard) + " to")
                stackNum = input()
                stackNum = int(stackNum)
        #else :
            #if(drawStackAsk()) :


    #Reset the game if the player wishes
    if(finished) :
        if(playAgain()) :
            finished = False
            d = deck()
            drawCount = 0
            stackCount = 0
            stack = cardStack()
            discardPile = cardStack()
            playerHand = Hand()
            playerHand.add(d.pop())
            playerHand.Show()
        else :
            break








